use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::{self, Instruction, BytecodeReader}, rtda::Frame};

// 根据栈顶引用是否是null进行跳转

// Branch if reference is null
#[derive(Debug, Default)]
pub struct IFNULL {
    offset: i32
}

impl Instruction for IFNULL {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.offset = reader.read_i16() as i32;
    }

    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let _ref = frame.borrow().get_operand_stack().borrow_mut().pop_ref();
        if _ref.is_none() {
            base::branch(frame, self.offset)
        }
    }
}

#[derive(Debug, Default)]
pub struct IFNONNULL {
    offset: i32
}

impl Instruction for IFNONNULL {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.offset = reader.read_i16() as i32;
    }

    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let _ref = frame.borrow().get_operand_stack().borrow_mut().pop_ref();
        if _ref.is_some() {
            base::branch(frame, self.offset)
        }
    }
}